home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / areuh.tar / areuh / load / acp.c
C/C++ Source or Header  |  1990-10-10  |  8KB  |  326 lines

  1. /*
  2.  * Authors :
  3.  *   Pierre DAVID (pda@masi.ibp.fr or pda@frunip62.bitnet)
  4.  *   Janick TAILLANDIER
  5.  *
  6.  * This program can be freely used or distributed as long as this
  7.  * note is kept.
  8.  *
  9.  * This program is provided "as is".
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <time.h>
  14.  
  15. typedef unsigned short uint16 ;
  16. typedef unsigned long uint32 ;
  17.  
  18. struct disc_hdr
  19. {
  20.     uint16  mlfi ;            /* Lif Id (0x8000) */
  21.     char   l_label [6] ;        /* volume label */
  22.     uint32 l_dstart ;            /* directory start record (usually 2) */
  23.     uint16 l_sys3000 ;            /* system 3000 (0x1000) */
  24.     uint16 l_spare1 ;            /* 0x0000 */
  25.     uint32 l_dirlen ;            /* directory length */
  26.     uint16 l_version ;            /* 0x0001 */
  27.     uint16 l_spare2 ;            /* 0x0000 */
  28.     uint32 trkpersurf ;            /* tracks per surface */
  29.     uint32 surfpermed ;            /* number of surfaces */
  30.     uint32 sectpertrk ;            /* records per track */
  31.     char   l_date [6] ;            /* date & time */
  32.     char   l_spare [213] ;        /* padding */
  33. } ;
  34.  
  35. struct lif_filent
  36. {
  37.     char    l_filnam [10] ;        /* file name */
  38.     uint16  l_filtyp ;            /* file type */
  39.     uint32  l_startsec ;        /* start record */
  40.     uint32  l_fillen ;            /* file length */
  41.     char    l_create_time [6] ;        /* date & time created */
  42.     uint16  l_flagwd ;            /* volume flag/number 0x8001 */
  43.     uint32  l_startexec ;        /* implementation */
  44. } ;
  45.  
  46. FILE *fp, *fplif, *fpw ;
  47. char filename[10] ;
  48. int type ;
  49. long int dir_sec, data_sec ;
  50. struct lif_filent dir_entry, areuh_dir ;
  51. struct disc_hdr header ;
  52. long int a = 0, b = 0, eod = 0 ;
  53.  
  54. #define DISK "/dev/dsk/floppy"
  55.  
  56. main (argc, argv)
  57. int argc ;
  58. char *argv[] ;
  59. {
  60.     long int magic ;
  61.  
  62.     if (argc!=2)
  63.     {
  64.         fprintf (stderr, "usage: acp file\n") ;
  65.         exit (1) ;
  66.     }
  67.  
  68.     if (!(fp=fopen (argv[1], "r")))
  69.     {
  70.         fprintf (stderr, "acp: cannot open file %s\n", argv[1]) ;
  71.         exit (1) ;
  72.     }
  73.     fread (&magic, sizeof (long int), 1 , fp) ;
  74.     if (magic!=0x1b080100)
  75.     {
  76.         fprintf (stderr, "acp: %s not a lex file\n", argv[1]) ;
  77.         exit (1) ;
  78.     }
  79.     if (!(fplif=fopen (DISK, "r")))
  80.     {
  81.         fprintf (stderr, "acp: cannot open %s for read\n", DISK) ;
  82.         exit (1) ;
  83.     }
  84.     if (!read_lif ())
  85.     {
  86.         fprintf (stderr, "acp: not a LIF disk\n") ;
  87.         exit (1) ;
  88.     }
  89.     read_file_infos () ;
  90.     search_dir () ;
  91.     if (!(fpw=fopen (DISK, "w")))
  92.     {
  93.         fprintf (stderr, "acp: cannot open %s for write\n", DISK) ;
  94.         exit (1) ;
  95.     }
  96.     write_data () ;
  97.     write_dir () ;
  98.     if (fclose (fplif))
  99.     {
  100.         fprintf (stderr, "acp: cannot close %s opened for read\n", DISK) ;
  101.         exit (1) ;
  102.     }
  103.     if (fclose (fpw))
  104.     {
  105.         fprintf (stderr, "acp: cannot close %s opened for write\n", DISK) ;
  106.         exit (1) ;
  107.     }
  108.     if (fclose (fp))
  109.     {
  110.         fprintf (stderr, "acp: cannot close file %s\n", argv[1]) ;
  111.         exit (1) ;
  112.     }
  113.     exit (0) ;
  114. }
  115.  
  116. skip (n)
  117. int n ;
  118. {
  119.     char c ;
  120.     int i ;
  121.  
  122.     for (i=1; i<=n; i++) fread (&c, 1, 1, fp) ;
  123. }
  124.  
  125. con (pvar, n)
  126. unsigned int *pvar ;
  127. int n ;
  128. {
  129.     int i ;
  130.     unsigned char areuh [256] ;
  131.  
  132.     fread (areuh, n, 1, fp) ;
  133.     *pvar = 0 ;
  134.     for (i=n-1; i>=0; i--)
  135.     {
  136.         *pvar = (*pvar * 16) + hex(areuh[i]) ;
  137.     }
  138. }
  139.  
  140. read_file_infos ()
  141. {
  142.     int i ;
  143.     unsigned int c ;
  144.     int length, length_sect ;
  145.  
  146.     for (i=0; i<8; i++)
  147.     {
  148.         con (&c, 2) ;
  149.         dir_entry.l_filnam[i] = (unsigned char) c ;
  150.     }
  151.     dir_entry.l_filnam[8] = ' ' ;
  152.     dir_entry.l_filnam[9] = ' ' ;
  153.     con (&c, 4) ;
  154.     dir_entry.l_filtyp = (unsigned short) c ;
  155.     skip (12) ;
  156.     con (&length, 5) ;
  157.     length_sect = (length -= 5 ) ;
  158.  
  159.     read_date (dir_entry.l_create_time) ;
  160.  
  161.     dir_entry.l_startexec = 0 ;
  162.     for (i=0; i<4; i++)
  163.     {  
  164.         c = length&0xff ;
  165.         dir_entry.l_startexec = (((unsigned int) dir_entry.l_startexec)*0x100)
  166.             + c ;
  167.         length /= 256 ;
  168.     }
  169.  
  170.     dir_entry.l_fillen = length_sect / 512 + ((length_sect%512) ? 1 : 0) ;
  171.     dir_entry.l_flagwd = (unsigned short int) 0x8001 ;
  172. }
  173.  
  174. read_date (str)
  175. char *str ;
  176. {
  177.     int i ;
  178.     long clock ;
  179.     struct tm *ptm ;
  180.  
  181.     clock = time ((long *) 0) ;
  182.     ptm = localtime (&clock) ;
  183.     str [0] = bcd (ptm->tm_year) ;
  184.     str [1] = bcd (ptm->tm_mon + 1) ;
  185.     str [2] = bcd (ptm->tm_mday) ;
  186.     str [3] = bcd (ptm->tm_hour) ;
  187.     str [4] = bcd (ptm->tm_min) ;
  188.     str [5] = '\0' ;
  189. }
  190.  
  191. int bcd (n)
  192. int n ;
  193. {
  194.     return (((n / 10) * 16) + (n % 10)) ;
  195. }
  196.  
  197. int read_lif ()
  198. {
  199.     fread (&header, sizeof (header), 1, fplif) ;
  200.     if (((unsigned short)header.mlfi)!=0x8000) return (0) ;
  201.     return (1) ;
  202. }
  203.  
  204. search_dir()
  205. {
  206.     struct lif_filent cur_dir_entry ;
  207.     long int compteur = 1, sod, sodn, limite ;
  208.  
  209.     sod = header.l_dstart  + header.l_dirlen ;
  210.     limite = ((unsigned) header.l_dirlen)*8 ;
  211.     fseek (fplif, header.l_dstart*0x100, 0) ;
  212.     fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ;
  213.     while ((cur_dir_entry.l_filtyp != 0xffff)&&(compteur<=limite))
  214.     {
  215.         if ((cur_dir_entry.l_filtyp == 0) &&
  216.             (cur_dir_entry.l_fillen >= dir_entry.l_fillen) && !a ) 
  217.         {
  218.             a = ftell (fplif) - 32 ;
  219.             sodn = cur_dir_entry.l_startsec ;
  220.         }
  221.         else if (strncmp (cur_dir_entry.l_filnam, dir_entry.l_filnam, 10) == 0)
  222.         {
  223.             b = ftell (fplif) - 32 ;
  224.             memcpy ((char *) &areuh_dir, (char *) &cur_dir_entry, 32) ;
  225.         }
  226.         sod = cur_dir_entry.l_startsec + cur_dir_entry.l_fillen ;
  227.         fread (&cur_dir_entry, sizeof(cur_dir_entry), 1, fplif) ;
  228.         compteur++ ;
  229.     }
  230.     if ((b) && (areuh_dir.l_fillen >= dir_entry.l_fillen))
  231.     {
  232.         a = b ;
  233.         b = 0 ;
  234.         sodn = areuh_dir.l_startsec ;
  235.     }
  236.     else if (!a)
  237.     {
  238.         if (compteur <= limite)
  239.         {
  240.             eod = ftell (fplif) ;
  241.             a = eod - 32 ;
  242.             sodn = sod ;
  243.             if (sodn+((unsigned) dir_entry.l_fillen)>=
  244.                                           ((unsigned) header.trkpersurf) *
  245.                                           ((unsigned) header.surfpermed) *
  246.                                           ((unsigned) header.sectpertrk))
  247.             {
  248.                 fprintf (stderr, "acp: no room in data area\n") ;
  249.                 exit (1) ;
  250.             }
  251.         }
  252.         else
  253.         {
  254.             fprintf (stderr, "acp: no room in directory area\n") ;
  255.             exit (1) ;
  256.         }
  257.     }
  258.     dir_entry.l_startsec = sodn ;
  259. }
  260.  
  261. write_data ()
  262. {
  263.     int c = 0, d ;
  264.  
  265.     fseek (fpw, ((unsigned long) dir_entry.l_startsec)*0x100, 0) ;
  266.     while ((d=getc (fp))!=EOF)
  267.     {
  268.         if (c)
  269.         {
  270.             fputc (hex(d)*16+hex(c), fpw) ;
  271.             c = 0 ;
  272.         }
  273.         else c = d ;
  274.     }
  275.     if (c) fputc (hex(c), fpw) ;
  276. }
  277.  
  278. int hex (c)
  279. int c ;
  280. {
  281.     return (((c>='A')&&(c<='F'))?c-'A'+10:c-'0') ;
  282. }
  283.  
  284. write_dir ()
  285. {
  286.     long int *plong, i ;
  287.  
  288.     update (a, &dir_entry) ;
  289.     if (b)
  290.     {
  291.         areuh_dir.l_filtyp = 0 ;
  292.         update (b, &areuh_dir) ;
  293.     }
  294.     if (eod)
  295.     {
  296.         plong = (long int *) &areuh_dir ;
  297.         for (i=1; i<=8; i++)
  298.         {
  299.             *plong = -1 ;
  300.             plong++ ;
  301.         }
  302.         update (eod, &areuh_dir) ;
  303.     }
  304. }
  305.  
  306. update (x, pdir)
  307. long int x ;
  308. struct lif_filent *pdir ;
  309. {
  310.     struct lif_filent sector[8] ;
  311.  
  312. /*
  313. fclose(fpw) ; fpw = fopen (DISK, "w") ;
  314. fclose(fplif) ; fplif = fopen (DISK, "r") ;
  315.     fseek (fplif, x, 0) ;
  316.     fread (sector, sizeof (sector), 1, fplif) ;
  317.     write (sector, sizeof (sector), 1, fpw) ;
  318.     memcpy (§or[(x/32) % 8], pdir, 32) ;
  319.     fseek (fpw, x, 0) ;
  320.     fwrite (sector, sizeof (sector), 1, fpw) ;
  321. */
  322.  
  323.     fseek (fpw, x, 0) ;
  324.     fwrite (pdir, sizeof *pdir, 1, fpw) ;
  325. }
  326.